# 导入所需的库
import pandas as pd
import aiomysql
import uvicorn
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import OAuth2PasswordBearer
from jose import jwt, JWTError
from datetime import datetime, timedelta
from pydantic import BaseModel, Field, constr
from datetime import datetime
from typing import Optional
from aiomysql import Connection
from contextlib import asynccontextmanager

# 创建 FastAPI 应用实例
app = FastAPI()

# 配置 CORS（跨源资源分享）
origins = ["*"]  # 允许所有来源的请求
methods = ["GET", "POST", "PUT", "DELETE"]  # 允许的 HTTP 方法
allow_credentials = True  # 允许发送身份验证信息（cookies）到服务器

# 添加 CORS 中间件到 FastAPI 应用
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 允许的所有来源
    allow_credentials=allow_credentials,  # 允许发送身份验证信息
    allow_methods=methods,  # 允许的所有 HTTP 方法
    allow_headers=["*"],  # 允许的所有头部信息
)


# 配置数据库连接
@asynccontextmanager
async def get_db():
    conn = await aiomysql.connect(
        host="rm-2zea30h4sh8g15zd1ho.mysql.rds.aliyuncs.com",
        port=3306,
        user="ai",
        password="Cpt123456@",
        db="talent_manage"
    )
    try:
        yield conn
    finally:
        conn.close()


# 配置 OAuth2 密码流
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")  # 定义获取令牌的 URL

# 定义 JWT 认证的密钥和算法
SECRET_KEY = "key"  # JWT 密钥
ALGORITHM = "HS256"  # JWT 算法


# 定义用户模型
class User(BaseModel):
    username: str  # 用户名
    password: str  # 密码


# 定义数据库中的用户模型
class UserInDB(User):
    id: int  # 用户 ID


# 定义注册用户模型
class UserRegister(BaseModel):
    username: str  # 用户名
    password: str  # 密码


# 跟进记录表
class FellowUpRecodesDataItem(BaseModel):
    id: Optional[int] = None  # 主键id
    user_id: Optional[int] = None  # 业务员id
    talent_id: Optional[int] = None  # 达人id
    fellow_up_type: Optional[str] = None  # 跟进类型
    fellow_up_record: Optional[str] = None  # 跟进记录
    product_link: Optional[str] = None  # 商品链接
    fellow_up_picture: Optional[str] = None  # 跟进图片
    remarks: Optional[str] = None  # 备注


class TalentDataItem(BaseModel):
    talent_id: Optional[int] = None  # varchar(255) - 达人id
    avatar: Optional[str] = None  # varchar(255) - 达人头像
    douyin_nickname: Optional[str] = None  # varchar(255) - 抖音昵称
    douyin_account: Optional[str] = None  # varchar(255), unique, not null - 抖音账号
    uid: Optional[str] = None  # varchar(255) - UID
    cooperation_code: Optional[str] = None  # varchar(255) - 合作码
    fan_portrait: Optional[str] = None  # varchar(255) - 粉丝画像
    product_category: Optional[str] = None  # varchar(255) - 带货类目
    follower_count: Optional[float] = None  # decimal(10, 2) - 粉丝数
    play_median: Optional[float] = None  # decimal(10, 2) - 播放中位数
    sales_amount_30days: Optional[float] = None  # decimal(10, 2) - 近30天销售额
    average_order_value: Optional[float] = None  # decimal(10, 2) - 平均客单价
    mcn_agency: Optional[str] = None  # varchar(255) - MCN机构
    tags: Optional[str] = None  # varchar(255) - 标签
    wechat_id: Optional[str] = None  # varchar(255) - 微信号
    contact_info: Optional[str] = None  # varchar(255) - 联系方式
    follow_media: Optional[str] = None  # varchar(255) - 跟进媒介
    notes: Optional[str] = None  # varchar(255) - 备注
    last_release_time: Optional[datetime] = None  # datetime - 最近释放时间
    release_reason: Optional[str] = None  # varchar(255) - 释放原因
    transaction_amount: Optional[float] = None  # decimal(10, 2) - 成交金额
    refund_amount: Optional[float] = None  # decimal(10, 2) - 退款金额
    average_commision_rate: Optional[float] = None  # decimal(10, 2) - 平均佣金率
    whether_sample: Optional[str] = None  # varchar(255) - 是否寄样
    payment_sales: Optional[int] = None  # bigint - 支付销量
    transaction_goods_count: Optional[int] = None  # bigint - 成交商品量
    play_count: Optional[int] = None  # bigint - 播放量
    interaction_count: Optional[int] = None  # bigint - 互动量
    video_post_count: Optional[int] = None  # bigint - 发布视频条数
    cumulative_cooperation_consumption: Optional[int] = None  # bigint - 累计合作劳务消耗
    search_after_view_count: Optional[int] = None  # bigint - 看后搜数量
    user_id: Optional[int] = None
    transfer_id: Optional[int] = None  # 转移达人的时候,指定转移给哪个业务员
    transfer_reason: Optional[str] = None  # 转移达人的原因
    sample_address: Optional[str] = None  # 寄样地址
    block_reason: Optional[str] = None  # 拉黑原因
    restore_reason: Optional[str] = None  # 恢复原因


# 内容表
class ContentDataItem(BaseModel):
    content_id: Optional[int] = None  # varchar(255) - id
    talent_id: Optional[int] = None  # varchar(255) - 达人id
    content_title: Optional[str] = None  # varchar(255)
    content_status: Optional[str] = None  # varchar(255)
    media_affiliation: Optional[str] = None  # 所属媒介
    content_remark: Optional[str] = None  # 内容备注
    collaboration_platform: Optional[str] = None  # 合作平台
    content_link: Optional[str] = None  # 内容链接
    publication_format: Optional[str] = None  # 发布形式
    play_num: Optional[int] = None  # 播放量
    # 点赞数, 评论数, 搜索数, 转发数, 消费金额(劳务费), 视频发布时间
    like_num: Optional[int] = None
    comment_num: Optional[int] = None
    search_num: Optional[int] = None
    forward_num: Optional[int] = None
    consume_amount: Optional[float] = None
    published_at: Optional[datetime] = None
    user_id: Optional[int] = None  # 用户id,也是follower_id,即业务员id
    associated_plan_id: Optional[int] = None  # 关联计划id


# 计划表
class PlanDataItem(BaseModel):
    id: Optional[int] = None  # varchar(255) - 计划id
    plan_name: Optional[str] = None  # varchar(255) - 计划名称
    plan_content: Optional[str] = None  # varchar(255) - 计划内容
    plan_remark: Optional[str] = None  # varchar(255) - 计划备注


# JWT 认证函数，用于创建访问令牌
def create_access_token(data: dict, expires_delta: timedelta):
    to_encode = data.copy()  # 复制数据字典
    expire = datetime.utcnow() + expires_delta  # 计算过期时间
    to_encode.update({"exp": expire})  # 将过期时间添加到数据字典中
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)  # 使用密钥和算法编码数据字典为 JWT 令牌
    return encoded_jwt  # 返回编码后的 JWT 令牌


# 获取当前登录用户函数
def get_current_user(token: str = Depends(oauth2_scheme)):
    # 定义认证异常
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,  # 状态码 401 未授权
        detail="Could not validate credentials",  # 详细信息
        headers={"WWW-Authenticate": "Bearer"},  # 认证头部信息
    )
    try:
        # 解码 JWT 令牌
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")  # 从 payload 中提取用户名
        if username is None:  # 如果用户名不存在，抛出认证异常
            raise credentials_exception
    except JWTError:  # 如果解码失败，抛出认证异常
        raise credentials_exception

    # 从数据库中获取用户信息
    user = get_user(username)
    if user is None:  # 如果用户不存在，抛出认证异常
        raise credentials_exception

    return user  # 返回用户信息


# 从数据库中获取用户信息的函数
async def get_user(username: str) -> UserInDB:
    async with get_db() as conn:
        async with conn.cursor() as cursor:
            query = "SELECT id, username, password FROM users WHERE username = %s"
            await cursor.execute(query, (username,))
            result = await cursor.fetchone()
            if result:
                return UserInDB(id=result[0], username=result[1], password=result[2])


# 注册接口
@app.post("/register", response_model=User)
async def register(user: UserRegister):
    async with get_db() as db:
        async with db.cursor() as cursor:
            query = "INSERT INTO users (username, password) VALUES (%s, %s)"  # 插入语句
            try:
                # 执行插入操作
                await cursor.execute(query, (user.username, user.password))
                await db.commit()
            except aiomysql.IntegrityError as e:
                if e.args[0] == 1062:  # Duplicate entry
                    raise HTTPException(status_code=400, detail="Username already registered")
                else:
                    raise HTTPException(status_code=500, detail="Database error")
            except Exception as e:
                raise HTTPException(status_code=500, detail=str(e))
    return {"username": user.username, "password": user.password}


# 登录接口
@app.post("/login")
async def login(user: User):
    db_user = await get_user(user.username)
    if db_user is None or db_user.password != user.password:
        raise HTTPException(status_code=400, detail="Incorrect username or password")
    # 加密
    access_token_expires = timedelta(minutes=30)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {
        "access_token": access_token,
        "token_type": "bearer",
        "user_id": db_user.id,
    }


# 达人公海添加达人接口
@app.post("/add_talent")
# 为了提高开发效率,这里不进行令牌校验了
async def add_talent(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            query = """
                    INSERT INTO 达人库 (
                        达人头像, douyin_nickname, douyin_account, UID, 合作码, 粉丝画像, 带货类目, 粉丝数, 播放中位数, 近30天销售额, 
                        平均客单价, MCN机构, 标签, 微信号, 联系方式, 跟进媒介, 备注, 最近释放时间, 释放原因, 成交金额, 
                        退款金额, 平均佣金率, 是否寄样, 支付销量, 成交商品量, 播放量, 互动量, 发布视频条数, 
                        累计合作劳务消耗, 看后搜数量, follower_id
                    ) VALUES (
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
                         %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 
                        %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
                          %s
                    )
                """
            try:
                await cursor.execute(query, (
                    talent_data_item.avatar,  # 达人头像
                    talent_data_item.douyin_nickname,  # 抖音昵称
                    talent_data_item.douyin_account,  # 抖音账号
                    talent_data_item.uid,  # UID
                    talent_data_item.cooperation_code,  # 合作码
                    talent_data_item.fan_portrait,  # 粉丝画像
                    talent_data_item.product_category,  # 带货类目
                    talent_data_item.follower_count,  # 粉丝数
                    talent_data_item.play_median,  # 播放中位数
                    talent_data_item.sales_amount_30days,  # 近30天销售额
                    talent_data_item.average_order_value,  # 平均客单价
                    talent_data_item.mcn_agency,  # MCN机构
                    talent_data_item.tags,  # 标签
                    talent_data_item.wechat_id,  # 微信号
                    talent_data_item.contact_info,  # 联系方式
                    talent_data_item.follow_media,  # 跟进媒介
                    talent_data_item.notes,  # 备注
                    talent_data_item.last_release_time,  # 最近释放时间
                    talent_data_item.release_reason,  # 释放原因
                    talent_data_item.transaction_amount,  # 成交金额
                    talent_data_item.refund_amount,  # 退款金额
                    talent_data_item.average_commision_rate,  # 平均佣金率
                    talent_data_item.whether_sample,  # 是否寄样
                    talent_data_item.payment_sales,  # 支付销量
                    talent_data_item.transaction_goods_count,  # 成交商品量
                    talent_data_item.play_count,  # 播放量
                    talent_data_item.interaction_count,  # 互动量
                    talent_data_item.video_post_count,  # 发布视频条数
                    talent_data_item.cumulative_cooperation_consumption,  # 累计合作劳务消耗
                    talent_data_item.search_after_view_count,  # 看后搜数量
                    talent_data_item.user_id  # 业务员id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果插入失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data added successfully"}  # 返回数据添加成功的消息


# 达人公海跟进达人接口
@app.post("/follow_up_talent")
async def follow_up_talent(talent_data_item: TalentDataItem):
    # 将该条达人的follower_id修改为当前登录用户的user_id
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                    update 达人库 set follower_id = %s where id=%s
                """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.user_id, talent_data_item.talent_id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果插入失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data update successfully"}  # 返回数据添加成功的消息


# 新增跟进记录接口
@app.post("/follow_up_record")
async def follow_up_record(fellow_up_record_data_item: FellowUpRecodesDataItem):
    # 将该条达人的follower_id修改为当前登录用户的user_id
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            insert_sql = """
                    INSERT INTO 跟进记录表 (follower_id, talent_id, 跟进类型, 跟进记录, 商品链接, 跟进图片, 备注)
                    values (%s, %s, %s, %s, %s, %s, %s)
                """
            try:
                await cursor.execute(insert_sql, (
                    fellow_up_record_data_item.user_id, fellow_up_record_data_item.talent_id,
                    fellow_up_record_data_item.fellow_up_type, fellow_up_record_data_item.fellow_up_record,
                    fellow_up_record_data_item.product_link,
                    fellow_up_record_data_item.fellow_up_picture, fellow_up_record_data_item.remarks
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果插入失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data insert successfully"}  # 返回数据添加成功的消息


# 新增和修改寄样地址接口
@app.post("/add_sample_address")
async def add_sample_address(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                    update 达人库 set sample_address=%s, 更新人id=%s where id =%s
                """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.sample_address, talent_data_item.user_id, talent_data_item.talent_id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果插入失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data insert successfully"}  # 返回数据添加成功的消息


# 编辑达人
@app.post("/update_talent")
async def update_talent(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                UPDATE 达人库
                SET
                    达人头像 = %s,
                    douyin_nickname = %s,
                    douyin_account = %s,
                    UID = %s,
                    合作码 = %s,
                    粉丝画像 = %s,
                    带货类目 = %s,
                    粉丝数 = %s,
                    播放中位数 = %s,
                    近30天销售额 = %s,
                    平均客单价 = %s,
                    MCN机构 = %s,
                    标签 = %s,
                    微信号 = %s,
                    联系方式 = %s,
                    跟进媒介 = %s,
                    备注 = %s,
                    最近释放时间 = %s,
                    释放原因 = %s,
                    成交金额 = %s,
                    退款金额 = %s,
                    平均佣金率 = %s,
                    是否寄样 = %s,
                    支付销量 = %s,
                    成交商品量 = %s,
                    播放量 = %s,
                    互动量 = %s,
                    发布视频条数 = %s,
                    累计合作劳务消耗 = %s,
                    看后搜数量 = %s,
                    follower_id = %s
                WHERE id = %s
            """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.avatar,  # 达人头像
                    talent_data_item.douyin_nickname,  # 抖音昵称
                    talent_data_item.douyin_account,  # 抖音账号
                    talent_data_item.uid,  # UID
                    talent_data_item.cooperation_code,  # 合作码
                    talent_data_item.fan_portrait,  # 粉丝画像
                    talent_data_item.product_category,  # 带货类目
                    talent_data_item.follower_count,  # 粉丝数
                    talent_data_item.play_median,  # 播放中位数
                    talent_data_item.sales_amount_30days,  # 近30天销售额
                    talent_data_item.average_order_value,  # 平均客单价
                    talent_data_item.mcn_agency,  # MCN机构
                    talent_data_item.tags,  # 标签
                    talent_data_item.wechat_id,  # 微信号
                    talent_data_item.contact_info,  # 联系方式
                    talent_data_item.follow_media,  # 跟进媒介
                    talent_data_item.notes,  # 备注
                    talent_data_item.last_release_time,  # 最近释放时间
                    talent_data_item.release_reason,  # 释放原因
                    talent_data_item.transaction_amount,  # 成交金额
                    talent_data_item.refund_amount,  # 退款金额
                    talent_data_item.average_commision_rate,  # 平均佣金率
                    talent_data_item.whether_sample,  # 是否寄样
                    talent_data_item.payment_sales,  # 支付销量
                    talent_data_item.transaction_goods_count,  # 成交商品量
                    talent_data_item.play_count,  # 播放量
                    talent_data_item.interaction_count,  # 互动量
                    talent_data_item.video_post_count,  # 发布视频条数
                    talent_data_item.cumulative_cooperation_consumption,  # 累计合作劳务消耗
                    talent_data_item.search_after_view_count,  # 看后搜数量
                    talent_data_item.user_id,  # 业务员id
                    talent_data_item.talent_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 转移达人
@app.post("/transfer_talent")
async def transfer_talent(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                UPDATE 达人库
                SET
                    follower_id = %s,
                    转移原因 = %s
                WHERE id = %s
            """
            try:
                await cursor.execute(update_sql, (

                    talent_data_item.transfer_id,  # 要转移给的业务员id
                    talent_data_item.transfer_reason,  # 转移原因
                    talent_data_item.talent_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 放入公海
@app.post("/put_into_open_sea")
async def put_into_open_sea(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                UPDATE 达人库
                SET follower_id = NULL,更新人id=%s
                WHERE id = %s
            """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.user_id,  # 业务员id
                    talent_data_item.talent_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 拉黑达人
@app.post("/block_talent")
async def block_talent(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                UPDATE 达人库
                SET is_blacklist='是',更新人id=%s,拉黑原因=%s,follower_id=NULL
                WHERE id = %s
            """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.user_id,  # 业务员id
                    talent_data_item.block_reason,
                    talent_data_item.talent_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 拉黑后恢复达人
@app.post("/restore_talent")
async def block_talent(talent_data_item: TalentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """
                UPDATE 达人库
                SET is_blacklist=NULL,更新人id=%s,恢复原因=%s,follower_id=%s
                WHERE id = %s
            """
            try:
                await cursor.execute(update_sql, (
                    talent_data_item.user_id,  # 业务员id
                    talent_data_item.restore_reason,  # 恢复原因
                    talent_data_item.transfer_id,  # 要转移给的业务员id
                    talent_data_item.talent_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 添加内容
@app.post("/add_content")
async def add_content(contend_data_item: ContentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            insert_sql = """ INSERT INTO 内容表 (
    talent_id,内容标题,内容状态,所属媒介, 内容备注,合作平台, 内容链接, 发布形式, play_num,  ike_num, comment_num, search_num, forward_num, consume_amount, published_at, follower_id, associated_plan_id
) VALUES ( %s, %s, %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s,  %s)
            """
            try:
                await cursor.execute(insert_sql, (
                    contend_data_item.talent_id,  # talent_id
                    contend_data_item.content_title,  # 内容标题
                    contend_data_item.content_status,  # 内容状态
                    contend_data_item.media_affiliation,  # 所属媒介
                    contend_data_item.content_remark,  # 内容备注
                    contend_data_item.collaboration_platform,  # 合作平台
                    contend_data_item.content_link,  # 内容链接
                    contend_data_item.publication_format,  # 发布形式
                    contend_data_item.play_num,  # play_num
                    contend_data_item.like_num,  # like_num
                    contend_data_item.comment_num,  # comment_num
                    contend_data_item.search_num,  # search_num
                    contend_data_item.forward_num,  # forward_num
                    contend_data_item.consume_amount,  # consume_amount
                    contend_data_item.published_at,  # published_at
                    contend_data_item.user_id,  # follower_id (即业务员id)
                    contend_data_item.associated_plan_id,  # associated_plan_id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 如果作为主程序运行，启动 FastAPI 应用
# 编辑内容
@app.post("/edit_content")
async def edit_content(contend_data_item: ContentDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            update_sql = """ 
                            UPDATE 内容表 SET 
                                talent_id = %s, 
                                内容标题 = %s, 
                                内容状态 = %s, 
                                所属媒介 = %s, 
                                内容备注 = %s, 
                                合作平台 = %s, 
                                内容链接 = %s, 
                                发布形式 = %s, 
                                play_num = %s, 
                                like_num = %s, 
                                comment_num = %s, 
                                search_num = %s, 
                                forward_num = %s, 
                                consume_amount = %s, 
                                published_at = %s, 
                                follower_id = %s, 
                                associated_plan_id = %s 
                            WHERE id = %s
                        """
            try:
                await cursor.execute(update_sql, (
                    contend_data_item.talent_id,  # talent_id
                    contend_data_item.content_title,  # 内容标题
                    contend_data_item.content_status,  # 内容状态
                    contend_data_item.media_affiliation,  # 所属媒介
                    contend_data_item.content_remark,  # 内容备注
                    contend_data_item.collaboration_platform,  # 合作平台
                    contend_data_item.content_link,  # 内容链接
                    contend_data_item.publication_format,  # 发布形式
                    contend_data_item.play_num,  # play_num
                    contend_data_item.like_num,  # like_num
                    contend_data_item.comment_num,  # comment_num
                    contend_data_item.search_num,  # search_num
                    contend_data_item.forward_num,  # forward_num
                    contend_data_item.consume_amount,  # consume_amount
                    contend_data_item.published_at,  # published_at
                    contend_data_item.user_id,  # follower_id (即业务员id)
                    contend_data_item.associated_plan_id,  # associated_plan_id
                    contend_data_item.content_id  # 主键id
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

        return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


# 新增计划
@app.post("/add_plan")
async def add_plan(plan_data_item: PlanDataItem):
    async with get_db() as db:
        async with db.cursor() as cursor:  # 使用异步上下文管理器创建游标
            insert_sql = """ INSERT INTO 计划表 (
    计划名称,计划内容,备注
) VALUES ( %s, %s, %s)
            """
            try:
                await cursor.execute(insert_sql, (
                    plan_data_item.plan_name,  # 计划名称
                    plan_data_item.plan_content,  # 计划内容
                    plan_data_item.plan_remark,  # 计划备注
                ))
                await db.commit()  # 提交事务
            except Exception as e:  # 如果更新失败，抛出 HTTP 500 错误并返回异常信息
                raise HTTPException(status_code=500, detail=str(e))

    return {"message": "Data updated successfully"}  # 返回数据更新成功的消息


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, ssl_keyfile="nginx.key",
                ssl_certfile="nginx.crt")  # 使用 uvicorn 启动应用，监听所有网络接口，端口 8000

# uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4 提升工作能力
# https://aimk.chinacpt.com:8000
